<?php

namespace cmf\lib;

use net\snoopy\Snoopy;
use think\Config;
use think\Model;

/**
 * Http通用接口
 *
 */
class HttpBase extends Model {

    var $dns = '';
    //注意这个参数放在最后输出结果的时候使用,中间过程全部设置为0
    //1get 2post
    var $method = 1;
    //1自带curl 2第三方
    var $curl_mode = 1;
    var $scheme_is = true;
    var $cookies = '';
    public $status = 0;
    public $curl = '';
    //1:curl/原生 2:Snoopy
    public $class = 0;

    //自定义初始化
    protected function initialize() {
        //需要调用`Model`的`initialize`方法
        parent::initialize();
        //TODO:自定义的初始化
    }

    function ver() {
        return "v0.0.1";
    }

    /**
     * post请求方法
     * @param string $url 访问的网站,包括 请求具体接口
     * @param unknown $data 任意
     * @return void
     */
    public function post($url = '', $data = '') {
        return self::send($url, $data, 'POST');
    }

    /**
     * http请求通用方法,自动识别http/https
     * @param string $url 访问的网站,包括 请求具体接口
     * @param unknown $data 任意
     * @param string $type 请求方式
     * @return void
     */
    public function send($url = '', $data = '', $type = 'GET') {
        //设置默认参数
        $timeout = 10;
        if (!extension_loaded('curl') && IS_SWOOLE === FALSE) {
            //走Snoopy/swoole下,stream_socket_client会连接超时.需要单独处理.
            $this->curl = new Snoopy();
            $this->curl->use_gzip = FALSE;
            $this->curl->read_timeout = $timeout;
            $this->curl->curl_mode = $this->curl_mode;
            $this->curl->scheme_is = $this->scheme_is;
            $this->class = 2;
        } else {
            $this->curl = new \Curl\Curl();
            $this->curl->setTimeout($timeout);
            $this->class = 1;
            // 不认证证书
            $this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
            $this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, false);
        }


        //构造访问包
        $this->dns = $url;
        $this->method = $type == 'GET' ? 1 : 2;


        //判断下.传进来的.是什么类型
        if (is_object($data)) {
            if ($this->class == 2) {
                $this->curl->set_submit_json();
                $submit_vars = $this->curl->_prepare_post_body(json_encode_ex($data), '', 1);
            } else {
                $submit_vars = json_encode_ex($data);
            }
        } elseif (is_array($data)) {
            if ($this->class == 2) {
                $this->curl->set_submit_normal();
                $submit_vars = $this->curl->_prepare_post_body($data, '', 1);
            } else {
                $submit_vars = $data;
            }
        } else {
            if ($this->class == 2) {
                $this->curl->set_submit_normal();
                if (!empty($data)) {
                    $submit_vars = $data;
                }
            } else {
                if (!empty($data)) {
                    $submit_vars = $data;
                }
            }
        }

        if ($this->class == 2) {
            if (!empty($data)) {
                if ($this->method == 1) {
                    $this->dns .= '?' . $submit_vars;
                }
            }
        }

        if ($this->class == 2) {
            //封装head头
            $this->curl->rawheaders['Accept-Language'] = 'zh-cn';
            $this->curl->rawheaders['Connection'] = 'keep-alive';

            $this->curl->agent = Config::get('agent');

            if (!empty($this->cookies)) {
                $this->curl->cookies = $this->cookies;
            }
        } else {
            $this->curl->setHeader('Accept-Language', 'zh-cn');
            $this->curl->setHeader('Connection', 'keep-alive');
            $this->curl->setUserAgent(Config::get('agent'));
//            if (!empty($this->cookies)) {
//                $this->curl->setCookies('foo', 'bar');
//            }
        }


        if ($this->method == 1) {
            $submit_url = $this->dns;

            if ($this->class == 2) {
                $this->curl->fetch($submit_url);
            } else {
                if (!empty($submit_vars)) {
                    $this->curl->get($submit_url, $submit_vars);
                } else {
                    $this->curl->get($submit_url);
                }
            }
        } else {
            $submit_url = $this->dns;
            if ($this->class == 2) {
                if (!empty($data)) {
                    $this->curl->submit($submit_url, $submit_vars, '', 0); //不允许编码
                } else {
                    $this->curl->fetch($submit_url);
                }
            } else {
                if (!empty($data)) {
                    $this->curl->post($submit_url, $submit_vars);
                } else {
                    $this->curl->get($submit_url);
                }
            }
        }

        if ($this->class == 2) {

            if (empty($this->cookies)) {
                $this->curl->setcookies();
                $this->cookies = $this->curl->cookies;
            }
            $response = $this->curl->results;

            //结果输出的形式，一般情况下会是json方式输出
            if (is_object($this->curl->results)) {
                $results = $this->curl->results;
                $response = json_decode($results, true);
            } else {
                $results = $this->curl->results;
                //判断下是什么格式的.
                if (is_json($results)) {
                    $response = json_decode($results, true);
                } else {
                    $response = $results;
                }
            }

            $this->status = intval($this->curl->status);
        } else {
            $response = '';
            $this->status = intval($this->curl->httpStatusCode);
            if ($this->curl->error) {
                $this->status = intval($this->curl->errorCode);
//                echo 'Error: ' . $this->curl->errorCode . ': ' . $this->curl->errorMessage . PHP_EOL;   
            }
            $results = $this->curl->response;
            //判断下是什么格式的.小数据包才判断.大数据包.丢给调用自己处理
            if (is_string($results) && strlen($results) < 1000 && is_json($results)) {
                $response = json_decode($results, true);
            } else {
                $response = $results;
            }
            $this->curl->close();
        }

        if ($this->status != 200) {
            $this->error = $this->status;
            return FALSE;
        }

        return $response;
    }

    /**
     * 调用snoopy的数组转url参数方法
     * $arr geturl 传入的参数
     * 列如 ：/index.php?g=Api&m=RentApi&m=Branch&a=getBranchLocation&uid=1374
     */
    public function prepare_post_body($arr, $type = 1) {
        $snoopy = new Snoopy();
        $ret = '?' . $snoopy->_prepare_post_body($arr, '', $type);
        return $ret;
    }

    public function download($url, $filename) {

        if (IS_WIN) {
            $curl_path = CMF_ROOT . '\swooleamoeba\extend\net\snoopy\curl\bin\curl.exe';
            // curl -o dodo1.jpg http:www.linux.com/dodo1.JPG
            $tempstr = $curl_path . ' -o  "' . $filename . '" "' . $url . '"';
//            $tempstr = iconv('utf-8', 'gbk', $tempstr);

            // 生成关键部分
            exec($tempstr, $results, $return);
            if ($return) {
                return false;
            }
            if (!is_file($filename)) {
                return FALSE;
            }
        } else {
            $curl = new \Curl\Curl();
            $curl->download($url, $filename);
            if (!is_file($filename)) {
                return FALSE;
            }
        }

        return true;
    }

}
